var $ = require("jquery");

function displayAjaxLoading(isShow) {
    var $ajaxLoadingBlock = $("#ajax-loading-block-window");
    if (!$ajaxLoadingBlock.length) {
        $ajaxLoadingBlock = $('<div id="ajax-loading-block-window" class="ajax-loading-block-window"><div class="loading-image"></div></div>').appendTo($('body'));
    }
    if (isShow) {
        $ajaxLoadingBlock.show();
    } else {
        $ajaxLoadingBlock.hide();
    }
};

var notificationBarTimeoutId;
/**
 * dislay notification top bar
 * @param  {string} message the htmlstring for notify
 * @param  {string} type    success, error
 * @param  {number} timeout the timeout to auto hide notification bar,
 */

function displayNotificationBar(message, type, timeout) {
    clearTimeout(notificationBarTimeoutId);
    var $notificationBar = $("#notificationBar");
    if (!$notificationBar.length) {
        // only binding delegate event once.
        $notificationBar = $('<div id="notificationBar" class="notification-bar"></div>').appendTo($('body'))
            .on("click", "div.close", function (evt) {
                $notificationBar.fadeOut('slow');
            })
            .on("mouseenter", ".content", function () {
                clearTimeout(notificationBarTimeoutId);
            });
    }
    // remove exist class.
    switch (type) {
        case "success":
            $notificationBar.removeClass("error");
            $notificationBar.addClass("success");
            break;
        case "error":
            $notificationBar.removeClass("success");
            $notificationBar.addClass("error");
            break;
    }
    var htmlCode = format('<div class="content">{1}</div>', message);
    // binding notification bar events.
    $notificationBar.html(htmlCode).append($('<div class="close"></div>')).fadeIn('slow');
    if (timeout && timeout > 0) {
        notificationBarTimeoutId = setTimeout(function () {
            $notificationBar.fadeOut('slow');
        }, timeout);
    }
};
/**
 * display message using popup notification
 * @param  {string}  message the message
 * @param  {string}  type    success or error
 * @param  {Boolean} isModal true is modal.
 */

function displayPopupNotification(message, type, isModal) {
    var title = '<div class="c-header"><i class="success-icon"></i><span>Notification</span><i class="close" title="close"></i></div>';

    if (type === 'error') {
        title = '<div class="c-header"><i class="error-icon"></i><span>Notification</span><i class="close" title="close"></i></div>';
    }
    alert.show(title, message, 400, null);
}
// The title,description is designed to push some share button such as "facebook","twitter"

function loadPage(site, pageTitle, pageDescription, currentURL) {
    /// <summary>
    /// This util function will used to go to new Social Network Service such as "facebook","twitter","google+"
    /// </summary>
    /// <param name="site">the siteUrl</param>
    /// <param name="pageTitle">the page title of our current page.</param>
    /// <param name="currentURL">current page url.</param>
    /// <param name="pageDescription">the page description of our current page.</param>
    currentURL = currentURL || window.document.title;
    pageTitle = pageTitle || window.location.href;
    pageDescription = pageDescription || "";

    var currentURL = encodeURIComponent(currentURL);
    var title = encodeURIComponent(pageTitle);
    var bodytext = encodeURIComponent(pageDescription);
    var newURL;
    var go = true;
    switch (site) {
        case "del.icio.us":
            newURL = "http://del.icio" + ".us/post?v=4" + ";url=" + currentURL + ";title=" + title;
            break;
        case "digg":
            newURL = "http://digg" + ".com/submit?phase=2&" + "url=" + currentURL + "&title=" + title + "&bodytext=" + bodytext + "&topic=tech_deals";
            break;
        case "reddit":
            newURL = "http://reddit" + ".com/submit?" + "url=" + currentURL + "&title=" + title;
            break;
        case "furl":
            newURL = "http://www.furl" + ".net/savedialog.jsp?" + "t=" + title + "&u=" + currentURL;
            break;
        case "rawsugar":
            newURL = "http://www.rawsugar" + ".com/home/extensiontagit/?turl=" + currentURL + "&tttl=" + title;
            break;
        case "stumbleupon":
            newURL = "http://www.stumbleupon" + ".com/submit?url=" + currentURL + "&title=" + title;
            break;
        case "blogmarks":
            break;
        case "facebook":
            newURL = "http://www.facebook" + ".com/share.php?src=bm&v=4" + "&u=" + currentURL + "&t=" + title;
            break;
        case "technorati":
            newURL = "http://technorati" + ".com/faves?sub=favthis&add=" + currentURL;
            break;
        case "spurl":
            newURL = "http://www.spurl" + ".net/spurl.php?v=3" + "&title=" + title + "&url=" + currentURL;
            break;
        case "simpy":
            newURL = "http://www.simpy" + ".com/simpy/LinkAdd.do?title=" + title + "&href=" + currentURL;
            break;
        case "ask":
            break;
        case "google":
            newURL = "http://www.google" + ".com/bookmarks/mark?op=edit&output=popup" + "&bkmk=" + currentURL + "&title=" + title;
            break;
        case "netscape":
            newURL = "http://www.netscape" + ".com/submit/?U=" + currentURL + "&T=" + title + "&C=" + bodytext;
            break;
        case "slashdot":
            newURL = "http://slashdot" + ".org/bookmark.pl?url=" + rawURL + "&title=" + title;
            break;
        case "backflip":
            newURL = "http://www.backflip.com/add_page_pop.ihtml?" + "title=" + title + "&url=" + currentURL;
            break;
        case "bluedot":
            newURL = "http://bluedot" + ".us/Authoring.aspx?" + "u=" + currentURL + "&t=" + title;
            break;
        case "kaboodle":
            newURL = "http://www.kaboodle" + ".com/za/selectpage?p_pop=false&pa=url" + "&u=" + currentURL;
            break;
        case "squidoo":
            newURL = "http://www.squidoo" + ".com/lensmaster/bookmark?" + currentURL;
            break;
        case "twitter":
            newURL = "http://twitthis" + ".com/twit?url=" + currentURL + "&title=" + title;
            break;
        case "bluedot":
            newURL = "http://blinkbits" + ".com/bookmarklets/save.php?" + "v=1&source_url=" + currentURL + "&title=" + title;
            break;
        case "blinkList":
            newURL = "http://blinkbits" + ".com/bookmarklets/save.php?" + "v=1&source_url=" + currentURL + "&title=" + title;
            break;
        case "browser":
            bookmarksite(pageTitle, rawURL);
            go = false;
            break
    }
    if (go == true) {
        window.open(newURL, "bookmarkWindow")
    }
}
/**
 * format string, format("test{1}", "new string");
 * @param  {string} str required
 * @return {string}     new replaced string.
 */

function format(str /*arguments*/) {
    // use this string as the format
    if (arguments.length == 1) {
        return str;
    }

    // walk through each argument passed in
    for (var fmt = str, ndx = 1; ndx < arguments.length; ++ndx) {
        // replace {0} with argument[0], {1} with argument[1], etc.
        fmt = fmt.replace(new RegExp('\\{' + ndx + '\\}', "g"), arguments[ndx]);
    }
    // return the formatted string
    return fmt;
}

function cookie(name, value, options) {
    if (typeof value != 'undefined') { // name and value given, set cookie
        options = options || {};
        if (value === null) {
            value = '';
            options.expires = -1;
        }
        if (enyo.isObject(value)) {
            value = JSON.stringify(value);
        }
        var expires = '';
        if (options.expires && (typeof options.expires == 'number' || options.expires.toUTCString)) {
            var date;
            if (typeof options.expires == 'number') {
                date = new Date();
                date.setTime(date.getTime() + (options.expires * 24 * 60 * 60 * 1000));
            } else {
                date = options.expires;
            }
            expires = '; expires=' + date.toUTCString(); // use expires attribute, max-age is not supported by IE
        }
        // CAUTION: Needed to parenthesize options.path and options.domain
        // in the following expressions, otherwise they evaluate to undefined
        // in the packed version for some reason...
        var path = options.path ? '; path=' + (options.path) : '';
        var domain = options.domain ? '; domain=' + (options.domain) : '';
        var secure = options.secure ? '; secure' : '';
        document.cookie = [name, '=', encodeURIComponent(value), expires, path, domain, secure].join('');
    } else { // only name given, get cookie
        var cookieValue = null;
        if (document.cookie && document.cookie != '') {
            var cookies = document.cookie.split(';');
            for (var i = 0; i < cookies.length; i++) {
                var cookie = enyo.trim(cookies[i]);
                // Does this cookie string begin with the name we want?
                if (cookie.substring(0, name.length + 1) == (name + '=')) {
                    cookieValue = decodeURIComponent(cookie.substring(name.length + 1));
                    break;
                }
            }
        }
        if (cookieValue && cookieValue.match(/^\s*\{/)) {
            try {
                cookieValue = JSON.parse(cookieValue);
            } catch (e) {
                console && console.log(e);
            }
        }
        return cookieValue;
    }
};

function openWindow(query, w, h, scroll) {
    var l = (screen.width - w) / 2;
    var t = (screen.height - h) / 2;

    winprops = 'resizable=0, height=' + h + ',width=' + w + ',top=' + t + ',left=' + l + 'w';
    if (scroll) winprops += ',scrollbars=1';
    var f = window.open(query, "_blank", winprops);
};

// normal uniform dialog.
var alert = {
    scrollTimeoutId: 0,
    // define close function.
    close: function () {
        this.$alert.fadeOut('fast');
    },
    // define dialog alert container 
    $alert: $("#fbalert").length ? $("#fbalert") : $('<div id="fbalert"><div class="fbalert-header" /><div class="fbalert-content"><div class="fbalert-body" /><div class="fbalert-footer" /></div></div>').appendTo($('body')).on("click", ".close", function () {
        alert.close();
    }),
    /**
     * the global uniform dialog
     * @param  {string}   title    the dialog title, can be html,
     * Note: we can inject selector `.close` can has existed click event to close current dialog.
     * @param  {string}   content  the html string for current dialog
     * @param  {number}   width the width for alert container
     * @param  {array}    buttons   the customized button in footer area
     *                             [{class:"", text:"ok", data:{}}]
     * @param  {Function} callbackFn the callbackFn
     */
    show: function (title, content, width, buttons, callbackFn, offset) {
        var $alert = this.$alert.css("width", width);
        var $alertBody = $alert.find(".fbalert-body"),
            $alertHeader = $alert.find(".fbalert-header"),
            $alertFooter = $alert.find(".fbalert-footer");
        callbackFn = $.isFunction(callbackFn) ? callbackFn : function () {
            alert.close();
        };
        // remove style attribute.
        $alertBody.html(content).removeAttr("style");
        $alertHeader.html(title ? title : document.title);
        $alertFooter.html(''); //reset footer 
        // if has costomized buttons in footer.
        if (buttons) {
            // float right reverse button order.
            var keys = buttons.reverse();
            for (var i = 0; i < buttons.length; i++) {
                var button = buttons[i];
                $alertFooter.append($("<div></div>").attr("class", "fbalert-button " + button["class"]).text(button.text).click(button.data, callbackFn));
            };

        } else {
            // show default button.
            $alertFooter.append($("<div>Ok</div>").attr('class', 'fbalert-button fbalert-button-primary').click(callbackFn));
        }
        var fbalert_position = function (info) {
            var top = 0;
            var left = ($(window).innerWidth() - $alert.width()) / 2 - parseInt($alert.css('paddingLeft'));
            if (typeof info == 'undefined') {
                top = (document.body.scrollTop || document.documentElement.scrollTop) + ($(window).innerHeight() / 2) - ($alert.height() / 2) - parseInt($alert.css('paddingTop'));
            } else {
                top = info.scrollTop - info.offsetTop + (info.clientHeight / 2) - ($alert.height() / 2) - parseInt($alert.css('paddingTop'))
            }
            // specific offset left,top value.
            if (offset) {
                top = offset.top || 0;
                left = offset.left || 0;
            }
            $alert.css('left', left + 'px');

            $alert.show().stop().animate({
                'top': top
            }, 'slow');

            // reset timeoutid.
            alert.scrollTimeoutId = 0;
        };
        $(window).scroll(function () {
            if (!alert.scrollTimeoutId && $alert.is(":visible")) {
                alert.scrollTimeoutId = setTimeout(fbalert_position, 200);
            }
        });
        // auto run.
        fbalert_position();
    }
};

/*
 ** nopCommerce ajax cart implementation
 */

var ajaxCart = {
    loadWaiting: false,
    usepopupnotifications: false,
    topcartselector: '',
    topwishlistselector: '',
    flyoutcartselector: '',

    init: function (usepopupnotifications, topcartselector, topwishlistselector, flyoutcartselector) {
        this.loadWaiting = false;
        this.usepopupnotifications = usepopupnotifications;
        this.topcartselector = topcartselector;
        this.topwishlistselector = topwishlistselector;
        this.flyoutcartselector = flyoutcartselector;
    },

    setLoadWaiting: function (display) {
        displayAjaxLoading(display);
        this.loadWaiting = display;
    },

    //add a product to the cart/wishlist from the catalog pages
    addproducttocart_catalog: function (urladd) {
        if (this.loadWaiting != false) {
            return;
        }
        this.setLoadWaiting(true);

        $.ajax({
            cache: false,
            url: urladd,
            type: 'post',
            success: this.success_desktop,
            complete: this.resetLoadWaiting,
            error: this.ajaxFailure
        });
    },

    //add a product to the cart/wishlist from the product details page (desktop version)
    addproducttocart_details: function (urladd, formselector) {
        if (this.loadWaiting != false) {
            return;
        }
        this.setLoadWaiting(true);

        $.ajax({
            cache: false,
            url: urladd,
            data: $(formselector).serialize(),
            type: 'post',
            success: this.success_desktop,
            complete: this.resetLoadWaiting,
            error: this.ajaxFailure
        });
    },

    //add a product to the cart/wishlist from the product details page (mobile devices version)
    addproducttocart_details_mobile: function (urladd, formselector, successredirecturl) {
        if (this.loadWaiting != false) {
            return;
        }
        this.setLoadWaiting(true);

        $.ajax({
            cache: false,
            url: urladd,
            data: $(formselector).serialize(),
            type: 'post',
            success: function (response) {
                //if (response.updatetopcartsectionhtml) {
                //    $(AjaxCart.topcartselector).html(response.updatetopcartsectionhtml);
                //}
                //if (response.updatetopwishlistsectionhtml) {
                //    $(AjaxCart.topwishlistselector).html(response.updatetopwishlistsectionhtml);
                //}
                if (response.message) {
                    //display notification
                    if (response.success == true) {
                        //we do not display success message in mobile devices mode
                        //just redirect a user to the cart/wishlist
                        location.href = successredirecturl;
                    } else {
                        //error
                        displayPopupNotification(response.message, 'error', true);
                        //displayStandardAlertNotification(response.message);
                    }
                    return false;
                }
                if (response.redirect) {
                    location.href = response.redirect;
                    return true;
                }
                return false;
            },
            complete: this.resetLoadWaiting,
            error: this.ajaxFailure
        });
    },

    success_desktop: function (response) {
        if (response.updatetopcartsectionhtml) {
            $(ajaxCart.topcartselector).html(response.updatetopcartsectionhtml);
        }
        if (response.updatetopwishlistsectionhtml) {
            $(ajaxCart.topwishlistselector).html(response.updatetopwishlistsectionhtml);
        }
        if (response.updateflyoutcartsectionhtml) {
            $(ajaxCart.flyoutcartselector).replaceWith(response.updateflyoutcartsectionhtml);
        }
        if (response.message) {
            //display notification
            if (response.success == true) {
                //success
                if (ajaxCart.usepopupnotifications == true) {
                    displayPopupNotification(response.message, 'success', true);
                } else {
                    //specify timeout for success messages
                    displayNotificationBar(response.message, 'success', 3500);
                }
            } else {
                //error
                if (ajaxCart.usepopupnotifications == true) {
                    displayPopupNotification(response.message, 'error', true);
                } else {
                    //no timeout for errors
                    displayNotificationBar(response.message, 'error', 0);
                }

            }
            return false;
        }
        if (response.redirect) {
            location.href = response.redirect;
            return true;
        }
        return false;
    },

    resetLoadWaiting: function () {
        ajaxCart.setLoadWaiting(false);
    },

    ajaxFailure: function () {
        alert('Failed to add the product to the cart. Please refresh the page and try one more time.');
    }
};
var common = $.extend($, {
    alert: alert,
    displayAjaxLoading: displayAjaxLoading,
    displayNotificationBar: displayNotificationBar,
    displayPopupNotification: displayPopupNotification,
    ajaxCart: ajaxCart,
    cookie: cookie,
    htmlEncode: function htmlEncode(value) {
        return $('<div/>').text(value).html();
    },
    htmlDecode: function htmlDecode(value) {
        return $('<div/>').html(value).text();
    },
    setLocation: function setLocation(url) {
        window.location.href = url;
    },
    openWindow: openWindow,
    loadPage: loadPage,
    format: format
});

module.exports = common;
